package com.sy.simpleegg.serialport.backscan

import android.util.Log
import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.serialport.base.BaseController
import com.sy.simpleegg.serialport.bean.ComData
import com.sy.simpleegg.serialport.util.ConvertHex
import com.sy.simpleegg.util.GsonUtil
import com.sy.logger.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.cnbleu.serialport.SerialPort

abstract class BackscanBaseController(
    portName: String,
    baudrate: SerialPort.BAUDRATE,
    stopb: SerialPort.STOPB,
    datab: SerialPort.DATAB,
    parity: SerialPort.PARITY,
    speed: Long
): BaseController(portName, baudrate, stopb, datab, parity, speed) {

    private val TAG = javaClass.simpleName

    private val START_SCAN = "RDC030;"

    private val STOP_SCAN = "RFC020;"

//    private val checkData = ConvertHex.bytetoString(byteArrayOf(68, 5))
    private val checkData = ConvertHex.bytetoString(byteArrayOf(6))

    //反扫字符串
    private var backSweepStr = ""

    private val mainScope = MainScope()

    private var receiveJob: Job? = null
    private var loopJob: Job? = null

    override fun onDataReceived(comData: ComData) {
        try {
            if (comData.data.isEmpty()){
                return
            }
            val bytes = comData.data
            val data: String = ConvertHex.bytetoString(bytes)
            logFile("收到反扫器数据:$data")

            if (data == checkData) {
                return
            }

            Log.d(TAG, "反扫数据DispRecData1：" + GsonUtil.getInstance()?.toJson(bytes))
            Log.d(TAG, "反扫数据DispRecData：$data")
            if (data != "") {
                var spaceStr = ""
                if (data.length > 4) {
                    var index = data.indexOf("\r\n")
                    if (index != -1) {
                        spaceStr = data.substring(0, index)
                    } else if (data.indexOf("\r") != -1) {
                        index = data.indexOf("\r")
                        spaceStr = data.substring(0, index)
                    } else {
                        spaceStr = data
                    }
                }
                Log.e(TAG, "spaceStr:$spaceStr")
                Logger.d("读取的反扫数据:$spaceStr", true)
                if (spaceStr.length > 0) {
                    backSweepStr += spaceStr
                    delayToSendData()
                    loopClose()
                } else {
                    startScan()
                }
            } else {
                //反扫数据为空，则重新打开反扫器继续扫描
                startScan()
            }

        }catch (e: Exception){
            e.printStackTrace()
            logFile("处理反扫器响应数据异常：${e.message}")
        }
    }

    override fun cmdTimeout(comData: ComData) {

    }

    private fun loopStart(){
        try {
            loopJob?.cancel()
            loopJob = mainScope.launch (Dispatchers.IO){
                delay(5000)
                startScan()
            }
        }catch (e: Exception){
            e.printStackTrace()
            logFile("循环开启反扫器异常：${e.message}")
        }
    }

    private fun loopClose(){
        loopJob?.cancel()
    }

    /**
     * 延迟获取最终的数据处理
     */
    private fun delayToSendData(){
        try {
            receiveJob?.cancel()
            receiveJob = mainScope.launch (Dispatchers.IO){
                delay(1000)
                if (backSweepStr.isNotEmpty()){
                    onReceive(backSweepStr)
                }
            }
        }catch (e: Exception){
            e.printStackTrace()
            logFile("延迟处理反扫器数据异常：${e.message}")
        }
    }

    fun startScan(){
        backSweepStr = ""
        loopStart()
        sendStr(START_SCAN)
    }

    fun stopScan(){
        loopClose()
        sendStr(STOP_SCAN)
    }

    private fun sendStr(dataStr: String){
        try {
            sendData(dataStr.toByteArray(), 500)
        }catch (e: Exception){
            logFile("反扫器 sendByte 发送指令异常：${e.message}")
        }
    }

    abstract fun onReceive(receivedData: String)
}